/**
 * @file spinlock.h
 * @author Wang Bo (1276106221@qq.com)
 * @brief C++11 原子自旋锁，仅头文件
 * @version 0.1
 * @date 2021-03-02
 * 
 * @copyright Copyright (c) 2021
 * 
 */
#ifndef __SPINLOCK_H__
#define __SPINLOCK_H__
#include <thread>
#include <atomic>

class CSpinLock final
{
public:
    CSpinLock() = default;
    ~CSpinLock() = default;
    
public:
    void lock() noexcept //解锁，绝不抛异常
    {
        for (;;)
        {
            if (!m_flag.test_and_set()) //原子变量TAS
            {
                return ; //成功则锁定返回
            }
            std::this_thread::yield(); //失败则让出
        }
    }

    void unlock() noexcept //解锁，绝不抛异常
    {
        m_flag.clear(); //清除标记
    }

private:
    std::atomic_flag m_flag {false};

private: //禁止复制
    CSpinLock(const CSpinLock& lock) = delete;
    CSpinLock& operator=(const CSpinLock&) = delete;
};

class LockGuard final
{
public:
    LockGuard(CSpinLock& lock) noexcept
        : m_lock(lock) //传引用，不复制
    {
        m_lock.lock();
    }
    ~LockGuard() noexcept
    {
        m_lock.unlock();
    }
private:
    CSpinLock& m_lock; //对CSpinLock对象的引用
private: //禁止复制
    LockGuard(const LockGuard&) = delete;
    LockGuard& operator=(const LockGuard&) = delete;
};


#endif // __SPINLOCK_H__